package com.navinfo.tripanalysis.common.arithmetic;

import com.navinfo.tripanalysis.common.arithmetic.common.CommonData;
import com.navinfo.tripanalysis.common.arithmetic.common.OuterStatisticData;
import com.navinfo.tripanalysis.common.arithmetic.common.VarNumberStatus;
import com.navinfo.tripanalysis.common.arithmetic.enums.EventType;
import com.navinfo.tripanalysis.common.arithmetic.manager.AbstractArithmetic;
import com.navinfo.tripanalysis.common.config.ConfigMap;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Optional;

/**
 * 东风新版，夜晚行程算法<br/>
 * 1.预设的夜晚行车时间段（如凌晨2:00-5:00）；<br/>
 * 2.当检测到车辆速度>5 公里/小时，或发动机转速>500 转/分钟，持续时间 T>20分钟；识别为一次夜晚行车事件。<br/>
 * 依赖{@link Mileage}里程油耗算法<br/>
 * 输出：统计、事件<br/>
 * @author web
 */
public class DrivingNight_DFN extends AbstractArithmetic<VarNumberStatus> {
    /**
     * 事件类型
     */
    private static final EventType EVENT_TYPE = EventType.drivingNight_DFN;
    /**
     * 起始时间： 2点
     */
    private int startHour = ConfigMap.getInteger("DFN_Night_Running_Time_Start");
    /**
     * 结束时间： 5点
     */
    private int endHour = ConfigMap.getInteger("DFN_Night_Running_Time_end");
    /**
     * 持续时长阈值，单位ms，默认1200 * 1000
     */
    private int durationThreshold = 1000 * ConfigMap.getInteger("DFN_Night_Running_Duration");

    /**
     * 判断当前是否为急减速
     */
    boolean isNightRunning() {
        CommonData commonData = getCommonData();
        int hour = LocalDateTime.ofInstant(Instant.ofEpochMilli(commonData.getGpsTime()), ZoneId.systemDefault()).getHour();

        //22：00 到 02:00 的情况
        if(startHour > endHour){
            return (hour>= startHour || (hour>=0 && hour< endHour) ) && (commonData.getSpeedKmh()>5 || commonData.getRotation()>500);
        }
        //02:00 到 05:00 的情况
        else{
            return hour>=startHour && hour<endHour && (commonData.getSpeedKmh()>5 || commonData.getRotation()>500);
        }

    }

    @Override
    public void calculate() {
        logger.debug("进入东风新版，夜晚运行算法.[terminalId:{}]", terminalId);
        VarNumberStatus var = super.getObj();
        boolean preStatus = var.isPreStatus();
        boolean curStatus = isNightRunning();

        //算法计算
        switch (getEventStatus(preStatus, curStatus)) {
            case START:
                startEventData(EVENT_TYPE);
                break;
            case IN:
                calcEventData(EVENT_TYPE);
                break;
            case END:
                calcEventData(EVENT_TYPE);
                endEventData();
                break;
            default:
                break;
        }

        //行程结束时要清理对应的未结束事件
        if (getCommonData().isTripLastNode()) {
            endEventData();
        }

        //设置上一个点状态、供下个点计算
        var.setPreStatus(curStatus);
        logger.debug("东风新版，夜晚运行算法结束.[terminalId:{}]", terminalId);
    }

    private void endEventData() {
        endEventData(EVENT_TYPE, (eventData, drivingData) -> {
            if (Optional.ofNullable(eventData.getDuration()).orElse(0L) > durationThreshold) {
                //更新统计变量
                getObj().addNumber(1);

                //放入事件输出列表
                drivingData.addEventDataToList(eventData);
            } else {
                logger.debug("东风新版冷车运行算法时间{}ms,小于阈值{}ms，不进行统计", Optional.ofNullable(eventData.getDuration()).orElse(0L), durationThreshold);
            }
        });
    }

    @Override
    public void collect(OuterStatisticData statisticDataOut) {
        VarNumberStatus var = getObj();
        statisticDataOut.setNightRunningNumber_DFN(var.getNumber());
    }
}
